package web.beans;

import java.io.Serializable;
import javax.ejb.EJB;
import javax.annotation.PostConstruct;
import java.util.List;
import java.text.SimpleDateFormat;
import javax.inject.Named;
import javax.faces.context.FacesContext;
 
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import javax.faces.application.FacesMessage;

import ejb.facade.EventFacade;
import ejb.entities.Event;
import ejb.entities.Invitation;
import ejb.entities.User;
import ejb.entities.WeatherForecast;
import ejb.facade.InvitationFacade;
import ejb.facade.UserFacade;
import ejb.facade.WeatherFacade;
import java.util.ArrayList;
import java.util.Calendar;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import org.primefaces.event.map.GeocodeEvent;
import org.primefaces.event.map.ReverseGeocodeEvent;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.GeocodeResult;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;

/**
 *
 * @author Andrea-Home
 */
@ViewScoped 
@Named("eventBean")
public class EventBean implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
    	@EJB
	private EventFacade evFacade;
        
        @EJB
	private UserFacade usFacade;
        
        @EJB
	private InvitationFacade inFacade;
        
        @EJB
	private WeatherFacade weaFacade;
        
        @Inject
	private Login login;
                      
        private Event evento;
        private WeatherForecast weatherfore;
        
        private Event selectedEvent;
        private List<Event> eventList;
        
        private String selectedUser;    
        
        private List<Invitation> inviteList;
        private Invitation newInvite;
        
        boolean edit;    
        
        //GeoMapManagement
        private MapModel geoModel;
        private MapModel revGeoModel;
        private String centerGeoMap = "41.850033, -87.6500523";
        private String centerRevGeoMap = "41.850033, -87.6500523";
        
        //Progress Bar Variable
        private Integer progress;
        
    /**
     * Constructor to initialize the entity event
     * Create a new GeoModel and Reverse geomodel to manage Google MAPS in web page
     * If into login entity is set a event parameter reload the event from the database and show that event
     * If there are not event processed by logit try to load parameters from login to pre-initialize title and dates
     */
    @PostConstruct
	public void Init() {
            geoModel = new DefaultMapModel();
            revGeoModel = new DefaultMapModel();
            
                this.selectedUser = null;
		this.evento = new Event();
                this.evento.setCreator(this.login.getUser());
                this.weatherfore = new WeatherForecast();
                this.eventList = new ArrayList<>();
                this.inviteList = new ArrayList<>();
                this.newInvite = null; 
                this.edit=false;
                //Inizialize bean if event ID parameter is setted
                if(login.getEventSelected()>= 0){
                    findReloadEventFromId(login.getEventSelected());
                    this.edit=true;
                    login.setEventSelected(-1);
                }else{
                    loadPreCacheEvent();
                }                   
	}
        
    /**
     * Takes parameters from login entity and initialize the Event object
     */
    public void loadPreCacheEvent(){
            if(login.getTitleSelected()!=null)
                if(login.getTitleSelected().length()>0){
                    this.evento.setTitle(login.getTitleSelected());
                }
            if(login.getDateStartSelected()!=null)
            {
                this.evento.setDateTimeStart(login.getDateStartSelected());
            }  
            if(login.getDateEndSelected()!=null)
            {
                this.evento.setDateTimeEnd(login.getDateEndSelected());
            }   
            login.setEventSelected(null, null, null);
        }
        
    /**
     * Take the id parameters from the login entity and reload the Event and invitation linked from the Database
     * @param id Primary key of the Event
     */
    public void findReloadEventFromId(int id){
            evento=evFacade.findEventById(id);
            this.weatherfore = this.evento.getIdWeather();
            inviteList=inFacade.findInvitationByEvent(evento);          
        }
        
    /**
     * Reset the entity
     */
    public void clear() {
                this.selectedUser = null;
                this.newInvite = null;
		this.evento = new Event();
		this.eventList = evFacade.findAll();
                this.inviteList = new ArrayList<>();
	}
        
    //GETTER Function

    /**
     * Returns progress integer used for progress bar
     * @return
     */
    
    public Integer getProgress() {
        if(progress == null) {
            progress = 0;
        }
        else {
            return progress;
        }  
        return progress;
    }           

    /**
     * Returns the weather forecast linked to the Events
     * @return
     */
    public WeatherForecast getWeatherfore() {        
        return weatherfore;
    }

    /**
     * Returns true if the user that invoked this function is the creator of the event and
     * the date and time when the event start is before the current date and time 
     * @return
     */
    public boolean isEditable(){
        //OBSOLETE TOO RESTRICTIVE
        //Check if the event is editable
        //The event is editable only if today is more than one day before the event start
        //Calendar c = Calendar.getInstance();
        //c.setTime(login.getToday()); 
        //c.add(Calendar.DATE, 1);
        //Date tomorrow = c.getTime();
        //if(this.evento.getDateTimeStart()!=null)
        //    return !tomorrow.after(this.evento.getDateTimeStart());
        //Check if i'm the owner of the event
        boolean check = true;
        if(!this.evento.getCreator().getUsername().equals(login.getUser().getUsername())) check = false;
        if(this.evento.getDateTimeStart()!=null){
            if(!this.evento.getDateTimeStart().after(login.getToday()) && this.edit) check = false;
        }
        return check;
    }
    
    /**
     * Returns true if the event is editable and is in the edit state
     * @return
     */
    public boolean isEdit() {
        return isEditable() && edit;
    }
    
    /**
     * Returns true if the event is editable and is not in the edit state
     * so this is a new event
     * @return
     */
    public boolean isNew(){
        return isEditable() && !edit;
    }

    /**
     *
     * @return
     */
    public Login getLogin() {
        return login;
    }

    /**
     *
     * @return
     */
    public EventFacade getEvFacade() {
        return evFacade;
    }

    /**
     *
     * @return
     */
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    /**
     *
     * @return
     */
    public EventFacade getevFacade() {
        return evFacade;
    }

    /**
     *
     * @return
     */
    public UserFacade getUsFacade() {
        return usFacade;
    }

    /**
     *
     * @return
     */
    public InvitationFacade getInFacade() {
        return inFacade;
    }

    /**
     * Returns the list of users invited to the Event
     * @return
     */
    public List<Invitation> getInviteList() {
        return inviteList;
    }

    /**
     * Returns the new invited created by user using web page
     * @return
     */
    public Invitation getNewInvite() {
        return newInvite;
    }
    
    /**
     *
     * @return
     */
    public Event getEvento() {
        return evento;
    }                    
    
    /**
     *
     * @return
     */
    public List<Event> getEventList() {
        return this.eventList;
    }

    /**
     * Returns the user selected using Invitation panel
     * @return
     */
    public String getSelectedUser() {
	return selectedUser;
    }
    
    /**
     *
     * @return
     */
    public Event getSelectedEvent() {
        return selectedEvent;
    } 
    
    /**
     *
     * @return
     */
        public List<Invitation> getInvitationList(){
		return this.inviteList;
    }
    
    //SETTER Function

    /**
     *
     * @param progress
     */
    
    public void setProgress(Integer progress) {
        this.progress = progress;
    }     
    
    /**
     *
     * @param weaFacade
     */
    public void setWeaFacade(WeatherFacade weaFacade) {
        this.weaFacade = weaFacade;
    }

    /**
     *
     * @param weatherfore
     */
    public void setWeatherfore(WeatherForecast weatherfore) {
        this.weatherfore = weatherfore;
    }

    /**
     *
     * @param edit
     */
    public void setEdit(boolean edit) {
        this.edit = edit;
    }

    /**
     *
     * @param login
     */
    public void setLogin(Login login) {
        this.login = login;
    }
        
    /**
     *
     * @param evFacade
     */
    public void setEvFacade(EventFacade evFacade) {
	this.evFacade = evFacade;
    }  

    /**
     *
     * @param invList
     */
    public void setInvitationList(List<Invitation> invList) {
        this.inviteList = invList;
    }           

    /**
     *
     * @param sEvent
     */
    public void setEvento(Event sEvent) {
        this.evento = sEvent;
    }   

    /**
     *
     * @param evFacade
     */
    public void setevFacade(EventFacade evFacade) {
        this.evFacade = evFacade;
    }

    /**
     *
     * @param usFacade
     */
    public void setUsFacade(UserFacade usFacade) {
        this.usFacade = usFacade;
    }

    /**
     *
     * @param inFacade
     */
    public void setInFacade(InvitationFacade inFacade) {
        this.inFacade = inFacade;
    }

    /**
     *
     * @param inviteList
     */
    public void setInviteList(List<Invitation> inviteList) {
        this.inviteList = inviteList;
    }

    /**
     *
     * @param newInvite
     */
    public void setNewInvite(Invitation newInvite) {
        this.newInvite = newInvite;
    } 
        
    /**
     *
     * @param eList
     */
    public void setEventList(List<Event> eList) {
	this.eventList = eList;
    }
	
    /**
     *
     * @param selectedUser
     */
    public void setSelectedUser(String selectedUser) {
	this.selectedUser = selectedUser;
    }

    /**
     *
     * @param selectedev
     */
    public void setSelectedEvent(Event selectedev) {
        this.selectedEvent = selectedev;
    }
    
    //EventBean Functions  

    /**
     * Search all the event using the same title
     */
    public void search(){		
		this.eventList = new ArrayList<>();

		for (Event s : evFacade.findAll()) {
			if (s.getTitle().toLowerCase().contains(this.getEvento().getTitle().toLowerCase()))
				eventList.add(s);
		}
	}
        
    /**
     *  Add an invitation for selectedUser to this event
     *  Checks if:
     *  - selected user is null 
     *  - the String provided is empty
     *  - the user is already invited
     */
    public void addInviteUser(){
        if(selectedUser != null){
        if(selectedUser.trim().length()>0){
            if(!inviteAlreadyAdded(selectedUser)){
		for (User s : usFacade.findAll()) {
			if (s.getUsername().toLowerCase().equals(this.selectedUser.toLowerCase())){
                                addInvitation(s);
                                FacesContext.getCurrentInstance().addMessage("inviteBtn", new FacesMessage(FacesMessage.SEVERITY_INFO, "Info", "User "+selectedUser+" invited!"));
                                break;
                        }
                }
            }else{
               FacesContext.getCurrentInstance().addMessage("inviteBtn", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "User "+selectedUser+" already invited!"));	             
            }
        }else{
            FacesContext.getCurrentInstance().addMessage("inviteBtn", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Search a user!"));	                      
        }
        }else{
            FacesContext.getCurrentInstance().addMessage("inviteBtn", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Search a user!"));
        }
    }
        
    private void SyncInvitation(){
		inviteList = this.inFacade.findInvitationByEvent(this.evento);
		//this.common_data.RefreshSkills();
	}
              
    /**
     * Remove invitations, weatherForecast and event from the database
     * Then came back to user home
     */
    public void removeEvent(){
		if(evento != null){			
                        for (Invitation s : inFacade.findInvitationByEvent(evento)){
                                if(s != null){
                                    inFacade.delete(s);
                                }		
                            }                       
                        evFacade.delete(evento);
                        if(evento.getIdWeather()!=null){
                            weaFacade.delete(evento.getIdWeather());
                        }
			this.SyncEvents();
                        this.SyncInvitation();
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Deleted!", "Event deleted from the system"));	
                        login.goToHome();
		}
	}

    /**
     * Add new events with weather forecast updated, invitations to the database
     * Then came back to user home
     */
    public void addEvent(){
		if(evento != null){			
			if(this.isNewEvent(evento)){
                            if(this.checkEventBeforeSave()){
                                this.evento.setCreator(login.getUser());
                                //ReloadWeather
                                this.takeWeatherForecast();
                                //First save the weather
                                weaFacade.save(this.weatherfore);
                                evFacade.save(evento);
                                boolean invadd=false;
                                for (Invitation s : this.inviteList){
                                    if(s != null){
                                        inFacade.save(s);
                                        invadd=true;
                                    }		
                                }  
                                if(invadd){
                                    this.SyncInvitation();
                                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Saved!", "Invitation added to event"));     
                                }
                                this.evento = new Event();
                                this.clear();
                                this.SyncEvents();
                                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Saved!", "Event added to the system"));	
                                login.goToHome();
                            }
                            }
			}
			else
			{
                     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Fatal!", "Event already exists"));
		}
	}
        
    private void SyncEvents(){
		eventList = evFacade.findAll();
	}
	
    /**
     * Checks if there is already an event with the same id 
     */
    private boolean isNewEvent(Event n){
		for (Event s : evFacade.findAll()) {
			if (s.getIdEvent()==n.getIdEvent())
				return false;
		}
		return true;
	}	             

    /**
     * Manages selection of the date in web page
     * @param event
     */
        public void onDateSelect(SelectEvent event){
            FacesContext facesContext = FacesContext.getCurrentInstance();
            SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
            facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Date Selected", format.format(event.getObject())));
        }
        
    /**
     *
     */
    public void click() {
            RequestContext requestContext = RequestContext.getCurrentInstance();
            requestContext.update("form:display");
            requestContext.execute("PF('dlg').show()");
        }
               
    /**
     * Adds a new invitation in invited List for the user in Pending state
     * @param addUs User invited
     */
    public void addInvitation(User addUs) {
		if(addUs != null){
                        newInvite = new Invitation();
                        newInvite.setInvstate("P");
			newInvite.setInviteduser(addUs);
                        newInvite.setEvent(this.evento);
                        this.inviteList.add(newInvite);
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Added!", "Invitation added to event"));
                }		     
	}
    
    /**
     * Removes the invitation from the database
     * @param inv
     */
    public void removeInvitation(Invitation inv){
        this.inviteList.remove(inv);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Removed!", "Invitation removed to event"));
    }
     
    /**
     * Checks if there is already an invitation for the same username
     * @param username
     */
    private boolean inviteAlreadyAdded(String username){
		for (Invitation s : this.inviteList) {
			if (s.getInviteduser().getUsername().toLowerCase().equals(username.toLowerCase()))
				return true;
		}
		return false;
	}     
                
    private boolean isNewInvite(User n){
            if(inFacade.findInvitationByEvent(this.evento).size()>0)
		for (Invitation s : this.inFacade.findInvitationByEvent(this.evento)) {
			if (s.getInviteduser().getUsername().toLowerCase().equals(n.getUsername().toLowerCase()))
				return false;
		}
	return true;
	}
        
    /**
     * Compelte user suggestion for the String insereted into invitation panel
     * @param condition
     * @return
     */
    public List<String> completeUser(String condition) {
		List<String> suggestions = new ArrayList<>();

		for (User s : usFacade.findAll()) {
                    if(!s.getUsername().equals(login.getUser().getUsername())){
			if (s.getUsername().toLowerCase().startsWith(condition.toLowerCase()))
				suggestions.add(s.getUsername());
                    }
		}

		return suggestions;
	}
    
    /**
     * Update the event with the new information available
     */
    public void updateEvent() {  
        //ReloadWeather
        this.takeWeatherForecast();
        //First delete old weather
        this.weatherfore.setIdWeather(evFacade.findEventById(this.evento.getIdEvent()).getIdWeather().getIdWeather());
        //Save new weatherForecast
        weaFacade.update(this.weatherfore);
	evFacade.update(this.evento);
        updateInvitation();
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Updated!", "Event changes saved!")); 
        login.goToHome();
    }  
    
    public boolean eventChanged(){
        boolean result = false;
        Event old= evFacade.findEventById(this.evento.getIdEvent());
        
        if(this.evento.getTitle()!=null || old.getTitle()!=null){
            if(!this.evento.getTitle().equals(old.getTitle())) result=true;
        }else if((this.evento.getTitle()==null && old.getTitle()!=null) || (this.evento.getTitle()!=null && old.getTitle()==null)){
            result=true;
        }            
        if(this.evento.getAddress()!=null || old.getAddress()!=null){
            if(!this.evento.getAddress().equals(old.getAddress())) result=true;
        }else if((this.evento.getAddress()==null && old.getAddress()!=null) || (this.evento.getAddress()!=null && old.getAddress()==null)){
            result=true;
        } 
        if(this.evento.getDateTimeStart()!=null || old.getDateTimeStart()!=null){
            if(!this.evento.getDateTimeStart().equals(old.getDateTimeStart())) result=true;
        }else if((this.evento.getDateTimeStart()==null && old.getDateTimeStart()!=null) || (this.evento.getDateTimeStart()!=null && old.getDateTimeStart()==null)){
            result=true;
        } 
        if(this.evento.getDateTimeEnd()!=null || old.getDateTimeEnd()!=null){
            if(!this.evento.getDateTimeEnd().equals(old.getDateTimeEnd())) result=true;
        }else if((this.evento.getDateTimeEnd()==null && old.getDateTimeEnd()!=null) || (this.evento.getDateTimeEnd()!=null && old.getDateTimeEnd()==null)){
            result=true;
        } 
       
        if(!(this.evento.getType()==old.getType())) result=true;
        
        if(this.evento.getCity()!=null || old.getCity()!=null){
            if(!this.evento.getCity().equals(old.getCity())) result=true;
        }else if((this.evento.getCity()==null && old.getCity()!=null) || (this.evento.getCity()!=null && old.getCity()==null)){
            result=true;
        } 
        if(this.evento.getDescription()!=null || old.getDescription()!=null){
            if(!this.evento.getDescription().equals(old.getDescription())) result=true;
        }else if((this.evento.getDescription()==null && old.getDescription()!=null) || (this.evento.getDescription()!=null && old.getDescription()==null)){
            result=true;
        } 
                  
        return result;
    }
    
    /**
     * Every time that the event is updated all the invitation change state to pending
     */
    public void updateInvitation(){
        boolean find=false;
        for (Invitation s : this.inviteList){
            find=false;
            for(Invitation alrinv : inFacade.findInvitationByEvent(evento)){
                if(s.getInviteduser().getUsername().equals(alrinv.getInviteduser().getUsername())){     
                    find=true;
                    break;
                }
            }
            if(!find){
                inFacade.save(s);
            }else{
                if(eventChanged()){
                    s.setInvstate("P");
                    inFacade.update(s);
                }
            }
        }  
        //Delete invitation deleted from the list
        for(Invitation dataInv : inFacade.findInvitationByEvent(evento)){
            find=false;
            for (Invitation listInv : this.inviteList){               
                 if(dataInv.getInviteduser().getUsername().equals(listInv.getInviteduser().getUsername())){ 
                     find=true;
                     break;
                 }
            }
            if(!find){
                inFacade.delete(dataInv);
            }
        }
            
    }
    
    /**
     * Takes the weather forecast provided by openweatherMaps API
     * City and End Date and Time are mandatory and could be setted in event
     * Manage a progress bar for the execution
     */
    public void takeWeatherForecast(){
      this.setProgress(0);
       if(this.evento.getCity() != null && this.evento.getDateTimeEnd() != null){
           if(!this.evento.getDateTimeEnd().before(login.getToday())){
           this.setProgress(progress + (int)(Math.random() * 65));
            weatherfore= weaFacade.getDailyWeatherForecast(this.evento.getCity(), this.evento.getDateTimeEnd(), false);
            if(weatherfore.getWeatherDesc() == null){
                weatherfore.setAvailable(false);
            }else  if(weatherfore.getWeatherDesc().isEmpty()){
                weatherfore.setAvailable(false);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Weather Forecast is not available!"));
            }else{
                this.evento.setIdWeather(weatherfore);                
            }
            this.setProgress(100);
           }else{
               this.setProgress(100);
               FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Weather Forecast not available for event in the past!"));
           }
       }else{
           this.setProgress(100);
           FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "City or end date are not defined!"));
       }
    }
    
    /**
     * Checks conditions for the correct saving of the event:
     * -    Title is mandatory
     * -    Address is Mandatory
     * -    City is Mandatory
     * -    Event End DateTime must be after Start DateTime
     * -    Event Start DateTime must be before End DateTime
     * -    Event DateTime start must be before current DateTime
     * -    Start and End Date Time are mandatory
     * @return
     */
    public boolean checkEventBeforeSave(){
        boolean result;
        result = true;
        if(this.evento.getTitle()==null){
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Title is required!"));              
            result = false;
        }
        if(this.evento.getAddress()==null){
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Address is required!"));              
            result = false;
        }
        if(this.evento.getCity()==null){
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "City is required!"));              
            result = false;
        }
        if(this.evento.getDateTimeStart()!=null && this.evento.getDateTimeEnd()!=null){
            if(this.evento.getDateTimeEnd().before(this.evento.getDateTimeStart())){
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "End event date before Start date!"));
                result=false;
            }else if(this.evento.getDateTimeEnd().compareTo(Calendar.getInstance().getTime())<=0){
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "You are not able to create event before current date and time!"));
                result=false;
            }else if(this.evento.getDateTimeStart().after(this.evento.getDateTimeEnd())){
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "Start event date after End date!"));
                result=false;
            }else if(this.evento.getDateTimeStart().compareTo(Calendar.getInstance().getTime())<=0){
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "You are not able to create event before current date and time!"));
                result=false;
            }
        }else{
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error!", "From and to Date and Time are required!"));              
            result = false;
        }
        
        
        return result;
    }
           
    /**
     * Manages Google MAPS location using the Address
     * @param event
     */
    public void onGeocode(GeocodeEvent event) {
        List<GeocodeResult> results = event.getResults();
         
        if (results != null && !results.isEmpty()) {
            LatLng center = results.get(0).getLatLng();
            centerGeoMap = center.getLat() + "," + center.getLng();
             
            for (int i = 0; i < results.size(); i++) {
                GeocodeResult result = results.get(i);
                geoModel.addOverlay(new Marker(result.getLatLng(), result.getAddress()));
                
            }
        }
    }
     
    /**
     *
     * @param event
     */
    public void onReverseGeocode(ReverseGeocodeEvent event) {
        List<String> addresses = event.getAddresses();
        LatLng coord = event.getLatlng();
         
        if (addresses != null && !addresses.isEmpty()) {
            centerRevGeoMap = coord.getLat() + "," + coord.getLng();
            revGeoModel.addOverlay(new Marker(coord, addresses.get(0)));
        }
    }
 
    /**
     *
     * @return
     */
    public MapModel getGeoModel() {
        return geoModel;
    }
 
    /**
     *
     * @return
     */
    public MapModel getRevGeoModel() {
        return revGeoModel;
    }
 
    /**
     *
     * @return
     */
    public String getCenterGeoMap() {
        return centerGeoMap;
    }
 
    /**
     *
     * @return
     */
    public String getCenterRevGeoMap() {
        return centerRevGeoMap;
    }
    
    /**
     *
     */
    public void onComplete() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Completed"));
    }
    
    /**
     *
     * @return
     */
    public boolean isWheatherAvailable(){
        if(this.weatherfore!=null)
            return this.weatherfore.isAvailable();
        else{
            return false;
        }
    }
    
}
